package org.csu.onlineedubackend.controller;

import org.springframework.scheduling.annotation.Scheduled;
import org.csu.onlineedubackend.dto.PhoneLoginDTO;
import org.csu.onlineedubackend.result.CommonResponse;
import org.csu.onlineedubackend.result.ResponseCode;
import org.csu.onlineedubackend.service.UserService;
import org.csu.onlineedubackend.util.CaptchaUtil;
import org.csu.onlineedubackend.dto.LoginDTO;
import org.csu.onlineedubackend.dto.RegisterDTO;
import org.csu.onlineedubackend.util.SmsUtil;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpSession;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.web.bind.annotation.*;
import org.csu.onlineedubackend.service.LogService;
import cn.dev33.satoken.stp.StpUtil;
import org.csu.onlineedubackend.entity.User;

import java.util.HashMap;
import java.util.Map;
import java.util.Set;

/**
 * 认证控制器
 */
@RestController
@RequestMapping("/api")
@CrossOrigin(origins = "*", maxAge = 3600)
public class AuthController {

    @Autowired
    private UserService userService;

    @Autowired
    private CaptchaUtil captchaUtil;
    
    @Autowired
    private SmsUtil smsUtil;

    @Autowired
    private LogService logService;

    @Autowired
    private StringRedisTemplate redisTemplate;

    /**
     * 获取验证码
     */
    @GetMapping("/captcha")
    public CommonResponse<Map<String, Object>> getCaptcha() {
        Map<String, Object> captchaInfo = captchaUtil.generateCaptcha();
        return CommonResponse.createForSuccess(
                ResponseCode.GetCaptchaSuccess.getCode(),
                ResponseCode.GetCaptchaSuccess.getDescription(),
                captchaInfo
        );
    }

    /**
     * 用户登录
     */
    @PostMapping("/login")
    public CommonResponse<Map<String, Object>> login(@RequestBody LoginDTO loginDTO, HttpServletRequest request) {
        String ip = request.getRemoteAddr();
        String userAgent = request.getHeader("User-Agent");
        try {
            // 参数校验
            if (loginDTO.getUsername() == null || loginDTO.getPassword() == null ||
                    loginDTO.getCaptchaCode() == null || loginDTO.getCaptchaKey() == null) {
                // 记录失败日志
                logService.recordLogin(null, loginDTO.getUsername(), ip, userAgent, false, "参数缺失");
                return CommonResponse.createForError(
                        ResponseCode.MissingParam.getCode(),
                        "用户名、密码或验证码不能为空"
                );
            }

            // 调用服务层处理登录
            Map<String, Object> loginResult = userService.login(loginDTO);

            // 准备返回给前端的数据
            Map<String, Object> responseData = new HashMap<>();
            Map<String, Object> userInfo = (Map<String, Object>) loginResult.get("userInfo");
            
            responseData.put("saTokenInfo", loginResult.get("saTokenInfo"));
            responseData.put("userId", userInfo.get("userId"));
            responseData.put("username", userInfo.get("username"));
            responseData.put("role", userInfo.get("role"));
            responseData.put("name", userInfo.get("name"));

            // 仅记录学生登录日志
            if (1 == (int) userInfo.get("role")) {
                logService.recordLogin(
                    (Integer) userInfo.get("userId"),
                    (String) userInfo.get("username"),
                    ip,
                    userAgent,
                    true,
                    "学生登录成功"
                );
            }

            return CommonResponse.createForSuccess(
                    ResponseCode.UserLoginSuccess.getCode(),
                    ResponseCode.UserLoginSuccess.getDescription(),
                    responseData
            );
        } catch (Exception e) {
            // 记录失败日志
            logService.recordLogin(null, loginDTO.getUsername(), ip, userAgent, false, "学生登录失败: " + e.getMessage());
            return CommonResponse.createForError(
                    ResponseCode.ERROR.getCode(),
                    e.getMessage()
            );
        }
    }
    
    /**
     * 发送短信验证码
     */
    @PostMapping("/send-sms")
    public CommonResponse<Map<String, Object>> sendSmsCode(@RequestParam String phone) {
        try {
            System.out.println("接收到发送短信验证码请求 - 手机号: " + phone);
            
            // 参数校验
            if (phone == null || phone.isEmpty()) {
                System.out.println("发送短信验证码失败: 手机号为空");
                return CommonResponse.createForError(
                        ResponseCode.MissingParam.getCode(),
                        "手机号不能为空"
                );
            }
            
            // 验证手机号格式
            if (!phone.matches("^1[3-9]\\d{9}$")) {
                System.out.println("发送短信验证码失败: 手机号格式不正确 - " + phone);
                return CommonResponse.createForError(
                        ResponseCode.Invalid.getCode(),
                        "手机号格式不正确"
                );
            }
            
            System.out.println("开始调用短信发送服务...");
            // 发送短信
            boolean success = smsUtil.sendSmsCode(phone);
            System.out.println("短信服务调用结果: " + (success ? "成功" : "失败"));
            
            // 返回结果
            Map<String, Object> result = new HashMap<>();
            result.put("success", success);
            
            if (success) {
                System.out.println("短信验证码发送成功，返回成功响应");
                return CommonResponse.createForSuccess(
                        ResponseCode.SendSmsSuccess.getCode(),
                        "短信验证码发送成功",
                        result
                );
            } else {
                System.out.println("短信验证码发送失败，返回错误响应");
                return CommonResponse.createForError(
                        ResponseCode.SendSmsFailed.getCode(),
                        "短信验证码发送失败"
                );
            }
        } catch (Exception e) {
            System.out.println("发送短信验证码时发生异常: " + e.getClass().getName() + ": " + e.getMessage());
            e.printStackTrace();
            return CommonResponse.createForError(
                    ResponseCode.SendSmsFailed.getCode(),
                    "短信验证码发送失败: " + e.getMessage()
            );
        }
    }
    
    /**
     * 检查用户名是否存在
     */
    @GetMapping("/check-username")
    public CommonResponse<Map<String, Object>> checkUsername(@RequestParam String username) {
        try {
            boolean exists = userService.checkUsernameExists(username);
            
            Map<String, Object> result = new HashMap<>();
            result.put("exists", exists);
            
            return CommonResponse.createForSuccess(
                    ResponseCode.Success.getCode(),
                    "查询成功",
                    result
            );
        } catch (Exception e) {
            return CommonResponse.createForError(
                    ResponseCode.Error.getCode(),
                    e.getMessage()
            );
        }
    }
    
    /**
     * 检查手机号是否存在
     */
    @GetMapping("/check-phone")
    public CommonResponse<Map<String, Object>> checkPhone(@RequestParam String phone) {
        try {
            boolean exists = userService.checkPhoneExists(phone);
            
            Map<String, Object> result = new HashMap<>();
            result.put("exists", exists);
            
            return CommonResponse.createForSuccess(
                    ResponseCode.Success.getCode(),
                    "查询成功",
                    result
            );
        } catch (Exception e) {
            return CommonResponse.createForError(
                    ResponseCode.Error.getCode(),
                    e.getMessage()
            );
        }
    }
    
    /**
     * 用户注册
     */
    @PostMapping("/register")
    public CommonResponse<Map<String, Object>> register(@RequestBody RegisterDTO registerDTO) {
        try {
            // 参数校验
            if (registerDTO.getUsername() == null || registerDTO.getPassword() == null ||
                    registerDTO.getPhone() == null || registerDTO.getSmsCode() == null ||
                    registerDTO.getName() == null || registerDTO.getAuthCode() == null) {
                return CommonResponse.createForError(
                        ResponseCode.MissingParam.getCode(),
                        "注册信息不完整"
                );
            }
            
            // 调用服务层处理注册
            Map<String, Object> registerResult = userService.register(registerDTO);
            
            return CommonResponse.createForSuccess(
                    ResponseCode.UserRegisterSuccess.getCode(),
                    "注册成功",
                    registerResult
            );
        } catch (Exception e) {
            return CommonResponse.createForError(
                    ResponseCode.UserRegisterFailed.getCode(),
                    e.getMessage()
            );
        }
    }

    /**
     * 用户手机号登录
     */
    @PostMapping("/login-by-phone")
    public CommonResponse<Map<String, Object>> loginByPhone(@RequestBody PhoneLoginDTO phoneLoginDTO, HttpServletRequest request) {
        String ip = request.getRemoteAddr();
        String userAgent = request.getHeader("User-Agent");
        try {
            // 参数校验
            if (phoneLoginDTO.getPhone() == null || phoneLoginDTO.getSmsCode() == null) {
                logService.recordLogin(null, phoneLoginDTO.getPhone(), ip, userAgent, false, "参数缺失");
                return CommonResponse.createForError(
                        ResponseCode.MissingParam.getCode(),
                        "手机号或验证码不能为空"
                );
            }

            // 调用服务层处理登录
            Map<String, Object> loginResult = userService.loginByPhone(phoneLoginDTO.getPhone(), phoneLoginDTO.getSmsCode());

            // 准备返回给前端的数据
            Map<String, Object> responseData = new HashMap<>();
            Map<String, Object> userInfo = (Map<String, Object>) loginResult.get("userInfo");
            
            responseData.put("saTokenInfo", loginResult.get("saTokenInfo"));
            responseData.put("userId", userInfo.get("userId"));
            responseData.put("username", userInfo.get("username"));
            responseData.put("role", userInfo.get("role"));
            responseData.put("name", userInfo.get("name"));

            if (1 == (int) userInfo.get("role")) {
                logService.recordLogin(
                    (Integer) userInfo.get("userId"),
                    (String) userInfo.get("username"),
                    ip,
                    userAgent,
                    true,
                    "学生手机号登录成功"
                );
            }

            return CommonResponse.createForSuccess(
                    ResponseCode.UserLoginSuccess.getCode(),
                    ResponseCode.UserLoginSuccess.getDescription(),
                    responseData
            );
        } catch (Exception e) {
            logService.recordLogin(null, phoneLoginDTO.getPhone(), ip, userAgent, false, "学生手机号登录失败: " + e.getMessage());
            return CommonResponse.createForError(
                    ResponseCode.ERROR.getCode(),
                    e.getMessage()
            );
        }
    }

    @PostMapping("/logout")
    public CommonResponse<String> logout(HttpServletRequest request) {
        Integer userId = null;
        String username = null;
        Integer role = null;

        // 1. 优先用 Sa-Token 登录态
        if (StpUtil.isLogin()) {
            userId = StpUtil.getLoginIdAsInt();
        } else {
            // 2. 尝试从请求头获取 token
            String headerToken = request.getHeader("satoken");
            if (headerToken != null && !headerToken.isEmpty()) {
                Object loginIdObj = StpUtil.getLoginIdByToken(headerToken);
                if (loginIdObj != null) {
                    userId = Integer.parseInt(loginIdObj.toString());
                }
            }
        }
//        System.out.println(userId);
        // 3. 查数据库获取用户信息
        if (userId != null) {
            User user = userService.getById(userId);
            if (user != null) {
                username = user.getUsername();
                role = user.getRole();
            }
        }
//        System.out.println(111);
        String ip = request.getRemoteAddr();
        String userAgent = request.getHeader("User-Agent");
        if (role != null && role == 1) { // 1为学生
//            System.out.println(222);
            logService.recordLogout(userId, username, ip, userAgent, "学生退出登录");
        }

        // Sa-Token登出
        if (StpUtil.isLogin()) {
            StpUtil.logout();
        }

        return CommonResponse.createForSuccess("登出成功");
    }

    @PostMapping("/heartbeat")
    public CommonResponse<String> heartbeat(HttpServletRequest request) {
        Integer userId = null;
        if (StpUtil.isLogin()) {
            userId = StpUtil.getLoginIdAsInt();
        } else {
            String headerToken = request.getHeader("satoken");
            if (headerToken != null && !headerToken.isEmpty()) {
                Object loginIdObj = StpUtil.getLoginIdByToken(headerToken);
                if (loginIdObj != null) {
                    userId = Integer.parseInt(loginIdObj.toString());
                }
            }
        }

        if (userId != null) {
            long now = System.currentTimeMillis();
            // 更新最后心跳时间（字符串存储）
            redisTemplate.opsForValue().set("heartbeat:" + userId, String.valueOf(now));

            // 记录IP和User-Agent
            String ip = request.getRemoteAddr();
            String userAgent = request.getHeader("User-Agent");

            redisTemplate.opsForHash().put("heartbeat_info:" + userId, "ip", ip != null ? ip : "unknown");
            redisTemplate.opsForHash().put("heartbeat_info:" + userId, "userAgent", userAgent != null ? userAgent : "unknown");

            System.out.println("心跳成功，用户ID：" + userId + "，IP：" + ip + "，Agent：" + userAgent);
        } else {
            System.out.println("心跳失败，未获取到用户ID");
        }

        return CommonResponse.createForSuccess("心跳成功");
    }
}

